<?php

// +----------------------------------------------------------------------
// | 版权所有 2017-2027 云南环拓科技有限公司，并保留所有权利。
// +----------------------------------------------------------------------
// | Copyright (c) 2017-2027 http://www.yn123.com All rights reserved.
// +----------------------------------------------------------------------
// | Notice: This code is not open source, it is strictly prohibited
// |         to distribute the copy, otherwise it will pursue its
// |         legal responsibility.
// | 注意：  这不是一个自由软件！您只能在不用于商业目的的前提下对程序代码进行修改和使用,
// |        不允许对程序代码以任何形式任何目的的再发布。
// +----------------------------------------------------------------------
// | Author: feraner <feraner@163.com> 
// | Date: 2019/12/20
// +----------------------------------------------------------------------

namespace app\common\services;


use app\common\constants\ApiConstant;
use app\common\facade\Arr;
use app\common\services\wechattemplate\MarketTemplateService;
use function GuzzleHttp\Promise\is_settled;
use library\tools\Data;
use think\Db;

/**
 * 二手商品发布 服务类
 * Class MarketPublishService
 * @package app\common\services
 * @author feraner<feraner@163.com>
 * @date 2019/12/20
 */
class MarketPublishService
{


    public function publishMarketGoods($postData)
    {
        $result = false;
        try {
            Db::startTrans();
            $checkPostData = $this->__beforePublishGoods($postData);
            if ($checkPostData) {
                $handlePostData = $this->__publishGoodsHandle($checkPostData);
                if ($handlePostData) {
                    $result = $this->__afterPublishGoods($handlePostData);
                    Db::commit();
                }
            }

        } catch (\Exception $e) {
            Db::rollback();
            throw $e;
        }
        return $result;
    }


    /**
     * 发布二手商品后续处理
     * @param $postData
     *
     * @return mixed
     * @throws \WeChat\Exceptions\InvalidResponseException
     * @throws \WeChat\Exceptions\LocalCacheException
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     */
    private function __afterPublishGoods($postData)
    {
        if (Arr::get($postData, 'aid')) {
            //后台管理人员发布，无需审核 暂无处理
        } else {
            //普通用户发布
            //1: 锁定需要的发布豆或者积分
            $updateData = [
                'updated_at'    => time()
            ];
            if (Arr::get($postData, 'publish_type', 0) == 1) {
                //使用积分发布
                $updateData['clock_credits'] = Db::raw('clock_credits + ' . Arr::get($postData, 'needCredits', 0));
                $updateData['credits'] = Db::raw('credits - ' . Arr::get($postData, 'needCredits', 0));
            }
            if (Arr::get($postData, 'publish_type', 0) == 2) {
                //使用发布豆发布
                $updateData['publish_bean'] = Db::raw('publish_bean - ' . Arr::get($postData['needBean'], 'needBean', 0));
                $updateData['clock_publish_bean'] = Db::raw('clock_publish_bean + ' . Arr::get($postData['needBean'], 'needBean', 0));
            }

            Db::name('user_wallet')
                ->where('user_id', Arr::get($postData, 'publish_id'))
                ->update($updateData);

            //2: 通知管理人员审核, 基于微信模版消息 手机微信审核
            (new MarketTemplateService())->sendAuditMarketGoods($postData);
        }

        return $postData;
    }



    /**
     * 发布二手商品数据库操作
     * @param $postData
     *
     * @return array
     * @throws \think\Exception
     * @throws \think\exception\PDOException
     */
    private function __publishGoodsHandle($postData)
    {
        $goodsInsertData = $this->__getMarketGoodsInsertData($postData);

        if ($goodsId = Arr::get($postData, 'id')) {
            $goodsInsertData['id'] = $goodsId;
        }
        $goodsInsertId = Data::save('market', $goodsInsertData);
        if ($goodsInsertId) {
            $goodsExtendData = [
                'market_id'    => $goodsId ?: $goodsInsertId,
                'content'   => Arr::get($postData, 'extendContent'),
            ];
            
            if ($extendId = Arr::get($postData, 'extendId')) {
                $goodsExtendData['id'] = $extendId;
            }
            $goodsExtendId = Data::save('market_extend', $goodsExtendData);
            if ($goodsExtendId) {
                return array_merge(
                    $postData,
                    [
                        'id'        => $goodsId ?: $goodsInsertId,
                        'extendId'  => $extendId ?: $goodsExtendId
                    ]
                );
            }
            new \Exception(
                ApiConstant::MARKET_PUBLISH_INSERT_MARKET_CONTENT_ERR_STR,
                ApiConstant::MARKET_PUBLISH_INSERT_MARKET_CONTENT_ERR
            );
        }
        new \Exception(
            ApiConstant::MARKET_PUBLISH_INSERT_MARKET_ERR_STR,
            ApiConstant::MARKET_PUBLISH_INSERT_MARKET_ERR
        );
    }



    /**
     * 发布二手商品前检查
     *
     * @param $postData
     *
     * @return mixed
     * @throws \think\Exception
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     * @throws \think\exception\PDOException
     * @throws \Exception
     */
    private function __beforePublishGoods($postData)
    {
        //before 地区转换
        $this->__converLocationToArea($postData);

        //如果是后台发布，不需要检测
        if (!Arr::get($postData, 'aid')) {
            //1: 检测用户是否可以发布,发布前需完善个人信息
            $userInfo = (new UserService())->userInfo(Arr::get($postData, 'publish_id'), ['extend']);
            if (!(new UserService())->checkUserInfoIsDone($userInfo)) {
                throw  new \Exception(
                    ApiConstant::USER_INFO_NOT_DONE_STR,
                    ApiConstant::USER_INFO_NOT_DONE
                );
            }

            //2: 发布二手是否有足够的积分或发布豆
            $needWealth = (new MarketPublishComputerService())->needWealth($postData);
            $userWallet = Db::name('user_wallet')
                ->where('user_id', Arr::get($userInfo, 'id'))
                ->find() ?: [];
            //2.1 检测是否有足够的积分
            if (Arr::get($userWallet, 'credits') < Arr::get($needWealth, 'needCredits')) {
                if (Arr::get($userWallet, 'publish_bean') < Arr::get($needWealth, 'needBean')) {
                    throw new \Exception(
                        ApiConstant::MARKET_PUBLISH_NOT_ENOUGH_BEAN_STR,
                        ApiConstant::MARKET_PUBLISH_NOT_ENOUGH_BEAN
                    );
                } else {
                    $postData['needBean'] = Arr::get($needWealth, 'needBean', 0);
                    $postData['publish_type'] = 2;
                }
            } else {
                $postData['needCredits'] = Arr::get($needWealth, 'needCredits', 0);
                $postData['publish_type'] = 1;
            }

        } else {
            //后台发布，不需要审核
            $postData['status'] = 3;
            $postData['is_show'] = 1;
            $postData['type'] = 1;//后台发布表示
            $postData['publish_type'] = 0;//后台发布，不扣除资源
        }

        return $postData;
    }






    public function saveMarketGoodsDraft($postData)
    {
        $result = false;
        try {
            Db::startTrans();
            $this->__converLocationToArea($postData);

            $goodsInsertData = $this->__getMarketGoodsInsertData($postData);

            if ($goodsId = Arr::get($postData, 'id')) {
                $goodsInsertData['id'] = $goodsId;
            }
            $goodsInsertId = Data::save('market', $goodsInsertData);
            if ($goodsInsertId) {
                $goodsExtendData = [
                    'market_id'    => $goodsId ?: $goodsInsertId,
                    'content'   => Arr::get($postData, 'extendContent', ''),
                ];
                if ($extendId = Arr::get($postData, 'extendId')) {
                    $goodsExtendData['id'] = $extendId;
                }
                $marketExtendId = Data::save('market_extend', $goodsExtendData);
                if ($marketExtendId) {
                    $result = [
                        'goodsId'         => Arr::get($goodsExtendData, 'market_id', 0),
                        'extendId'      => $extendId ?: $marketExtendId
                    ];
                    Db::commit();
                } else {
                    throw new \Exception(
                        ApiConstant::MARKET_PUBLISH_INSERT_MARKET_CONTENT_ERR_STR,
                        ApiConstant::MARKET_PUBLISH_INSERT_MARKET_CONTENT_ERR
                    );
                }
            } else {
                throw new \Exception(
                    ApiConstant::MARKET_PUBLISH_INSERT_MARKET_ERR_STR,
                    ApiConstant::MARKET_PUBLISH_INSERT_MARKET_ERR
                );
            }
        } catch (\Exception $e) {
            $result = false;
            Db::rollback();
        }
        return $result;
    }




    /**
     * 二手商品 表需要插入到数据
     * @param $postData
     *
     * @return array
     */
    private function __getMarketGoodsInsertData($postData)
    {
        $insertData = [
            'tid'               => Arr::get($postData, 'tid'),
            'name'              => Arr::get($postData, 'name', ''),
            'logo'              => Arr::get($postData, 'logo', ''),
            'image'             => Arr::get($postData, 'image', ''),
            'is_show'           => Arr::get($postData, 'is_show', 0),
            'status'            => Arr::get($postData, 'status', 1),
            'oprice'            => Arr::get($postData, 'oprice', 0),
            'depreciation'      => Arr::get($postData, 'depreciation', '全新'),
            'money'             => Arr::get($postData, 'money', 0),
            'number'            => Arr::get($postData, 'number' , 1),
            'contacts'          => Arr::get($postData, 'contacts', ''),
            'mobile'            => Arr::get($postData, 'mobile', ''),
            'wechat_num'        => Arr::get($postData, 'wechat_num', ''),
            'qq_num'            => Arr::get($postData, 'qq_num', ''),
            'type'              => Arr::get($postData, 'type', 0),
            'provinces_id'      => Arr::get($postData, 'provincesId', 0),
            'city_id'           => Arr::get($postData, 'cityId', 0),
            'county_id'         => Arr::get($postData, 'countyId', 0),
            'address'           => Arr::get($postData, 'address', ''),
            'publish_id'        => Arr::get($postData, 'publish_id', 0),
            'aid'               => Arr::get($postData, 'aid', 0),
            'created_at'        => time(),
            'updated_at'        => time(),
            'provinces_name'    => Arr::get($postData, 'provinces_name', 0),
            'top'               => Arr::get($postData, 'top', 0),
            'click_num'         => Arr::get($postData, 'click_num', 0),
            'share_num'         => Arr::get($postData, 'share_num', 0),
            'collect_num'       => Arr::get($postData, 'collect_num', 0),
            'replay'            => Arr::get($postData, 'replay', ''),
            'publish_type'      => Arr::get($postData, 'publish_type', 0),
        ];
        if (Arr::get($postData, 'publish_type') == 1) {
            $insertData['publish_need_wealth'] = Arr::get($postData, 'needCredits', 0);
        }
        if (Arr::get($postData, 'publish_type') == 2) {
            $insertData['publish_need_wealth'] = Arr::get($postData, 'needBean', 0);
        }
        return $insertData;
    }






    /**
     * 地址转成获取到系统中的地址ID
     * @param $postData
     */
    private function __converLocationToArea(&$postData)
    {
        $location = array_values(array_filter(explode(' ', trim(Arr::get($postData, 'provinces_name')))));
        $provincesId = Db::name('area')
            ->where('area_name', 'LIKE', '%' . Arr::get($location, 0) . '%')
            ->where('area_deep', 1)
            ->value('area_id') ?: 0;
        $cityId = Db::name('area')
            ->where('area_name', 'LIKE', '%' . Arr::get($location, 1) . '%')
            ->where('area_deep', 2)
            ->value('area_id') ?: 0;
        $countyId = Db::name('area')
            ->where('area_name', 'LIKE', '%' . Arr::get($location, 2) . '%')
            ->where('area_deep', 3)
            ->value('area_id') ?: 0;

        $postData['provincesId'] = $provincesId;
        $postData['cityId'] = $cityId;
        $postData['countyId'] = $countyId;
        $postData['provinces_id'] = $provincesId;
        $postData['city_id'] = $cityId;
        $postData['county_id'] = $countyId;
    }


    /**
     * 审核通过二手商品
     * @param $goodsId
     * @param $userId
     *
     * @return bool|int|string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function approvedGoods($goodsId, $userId)
    {
        $result = false;
        $goodsInfo = Db::name('market')
            ->where('id', $goodsId)
            ->where('status', 'IN', [2,4])
            ->find() ?: [];
        if ($goodsInfo) {
            try {
                Db::startTrans();
                //1：修改兼职状态
                $result = Db::name('market')
                    ->where('id', $goodsId)
                    ->update([
                        'status'        => 3,
                        'is_show'       => 1,
                        'updated_at'    => time()
                    ]);
                if ($result) {
                    //2：扣除积分|发布豆 + 消耗记录
                    $updateData = [
                        'updated_at'    => time()
                    ];
                    if (Arr::get($goodsInfo, 'publish_type') == 1) {
                        //使用积分发布
                        $updateData['clock_credits'] = Db::raw('clock_credits - ' . Arr::get($goodsInfo, 'publish_need_wealth', 0));
                        $updateData['used_credits'] = Db::raw('used_credits + ' . Arr::get($goodsInfo, 'publish_need_wealth', 0));
                    }
                    if (Arr::get($goodsInfo, 'publish_type') == 2) {
                        //使用发布豆发布
                        $updateData['clock_publish_bean'] = Db::raw('clock_publish_bean - ' . Arr::get($goodsInfo, 'publish_need_wealth', 0));
                        $updateData['used_publish_bean'] = Db::raw('used_publish_bean + ' . Arr::get($goodsInfo, 'publish_need_wealth', 0));
                        //消耗发布豆获得积分
                        $giveCredits = Arr::get($goodsInfo, 'publish_need_wealth', 0) * (sysconf('used_bean_give_credits') ?: 0);
                        $updateData['credits'] = Db::raw('credits + ' . $giveCredits);
                    }
                    $result = Db::name('user_wallet')
                        ->where('user_id', Arr::get($goodsInfo, 'publish_id'))
                        ->update($updateData);

                    if ($result) {
                        if (Arr::get($goodsInfo, 'publish_need_wealth')) {
                            if (Arr::get($goodsInfo, 'publish_type') == 1) {
                                //积分消耗记录
                                Db::name('user_credits_log')
                                    ->insertGetId([
                                        'user_id'           => Arr::get($goodsInfo, 'publish_id'),
                                        'credits'           => Arr::get($goodsInfo, 'publish_need_wealth', 0),
                                        'type'              => 2,
                                        'kind'              => 5,
                                        'created_at'        => time(),
                                        'updated_at'        => time()
                                    ]);
                            }
                            if (Arr::get($goodsInfo, 'publish_type') == 2) {
                                //发布豆消耗记录
                                if (Arr::get($goodsInfo, 'publish_need_wealth')) {
                                    Db::name('user_recharge_log')
                                        ->insertGetId([
                                            'user_id'           => Arr::get($goodsInfo, 'publish_id'),
                                            'recharge_money'    => 0,
                                            'type'              => 2,
                                            'publish_bean'      => Arr::get($goodsInfo, 'publish_need_wealth'),
                                            'kind'              => 4,
                                            'created_at'        => time(),
                                            'updated_at'        => time()
                                        ]);
                                }
                                //消耗发布豆送的积分记录
                                if (isset($giveCredits) && $giveCredits) {
                                    Db::name('user_credits_log')
                                        ->insertGetId([
                                            'user_id'           => Arr::get($goodsInfo, 'publish_id'),
                                            'credits'           => $giveCredits,
                                            'type'              => 1,
                                            'kind'              => 6,
                                            'created_at'        => time(),
                                            'updated_at'        => time()
                                        ]);
                                }
                            }
                        }
                        Db::commit();
                        (new MarketTemplateService())->checkMarketGoodsSuccess($goodsInfo);
                    } else {
                        throw new \Exception('扣除发布资源失败！');
                    }
                }
            } catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }
        }
        return $result;
    }


    /**
     * 审核拒绝二手商品
     * @param $goodsId
     * @param $userId  审核人员ID
     * @param $message
     *
     * @return bool|int|string
     * @throws \think\db\exception\DataNotFoundException
     * @throws \think\db\exception\ModelNotFoundException
     * @throws \think\exception\DbException
     */
    public function rejectGoods($goodsId, $userId, $message)
    {

        $result = false;
        $goodsInfo = Db::name('market')
            ->where('id', $goodsId)
            ->where('status', 'IN', [2,4])
            ->find() ?: [];
        if ($goodsInfo) {
            try {
                Db::startTrans();
                //1：修改二手商品状态
                $result = Db::name('market')
                    ->where('id', $goodsId)
                    ->update([
                        'status'        => 4,
                        'is_show'       => 0,
                        'replay'        => $message,
                        'updated_at'    => time()
                    ]);
                if ($result) {
                    //2:返回锁定的资源
                    $updateData = [
                        'updated_at'    => time()
                    ];
                    if (Arr::get($goodsInfo, 'publish_type') == 1) {
                        //使用积分发布
                        $updateData['credits'] = Db::raw('credits + ' . Arr::get($goodsInfo, 'publish_need_wealth', 0));
                        $updateData['clock_credits'] = Db::raw('clock_credits - ' . Arr::get($goodsInfo, 'publish_need_wealth', 0));
                    }
                    if (Arr::get($goodsInfo, 'publish_type') == 2) {
                        //使用发布豆发布
                        $updateData['publish_bean'] = Db::raw('publish_bean + ' . Arr::get($goodsInfo, 'publish_need_wealth', 0));
                        $updateData['clock_publish_bean'] = Db::raw('clock_publish_bean - ' . Arr::get($goodsInfo, 'publish_need_wealth', 0));
                    }
                    Db::name('user_wallet')
                        ->where('user_id', Arr::get($goodsInfo, 'publish_id'))
                        ->update($updateData);

                    Db::commit();
                    (new MarketTemplateService())->checkMarketGoodsFalse($goodsInfo, $message);
                }
            } catch (\Exception $e) {
                Db::rollback();
                throw $e;
            }
        }
        return $result;
    }










}
